package com.front.frontdemo.advice;

import com.example.comm.dataComm.BaseResponse;
import com.example.comm.dataComm.ResponseCode;
import com.example.comm.dataComm.ResponseResult;
import com.example.comm.exceptions.LogicException;
import com.example.comm.exceptions.NoResultException;
import com.example.comm.exceptions.WmsException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 异常统一处理类
 *
 * @author raines
 */
@ControllerAdvice("com.front.frontdemo")
@Slf4j
public class GlobalExceptionHandler {

    public static final boolean DEBUG = false;

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> allException(HttpServletRequest request, Exception exception) {
        StackTraceElement stackTraceElement = exception.getStackTrace()[0];
        String message;
        if (DEBUG) {
            message = exception.getMessage() + " " + exception.getClass()
                    + " File:" + stackTraceElement.getFileName() + " Line:" + stackTraceElement.getLineNumber()
                    + " Method:" + stackTraceElement.getMethodName();
        } else {
            message = exception.getMessage();
        }
        List<String> errors = new ArrayList<>();
        errors.add(message);
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.FAIL.code, message, data);
    }

    /**
     * 非法参数异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> handleTestException(HttpServletRequest request, IllegalArgumentException exception) {
        String message = exception.getMessage();
        List<String> errors = new ArrayList<>();
        errors.add(message);
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.FAIL.code, message, data);
    }

    /**
     * 请求WMS异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(WmsException.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> handleTestException(HttpServletRequest request, WmsException exception) {
        String message = exception.getMessage();
        List<String> errors = new ArrayList<>();
        errors.add(message);
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.FAIL.code, message, data);
    }


    /**
     * IllegalState异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(IllegalStateException.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> handleTestException(HttpServletRequest request, IllegalStateException exception) {
        String message = exception.getMessage();
        List<String> errors = new ArrayList<>();
        errors.add(message);
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.FAIL.code, message, data);
    }

    /**
     * 业务逻辑处理异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(LogicException.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> handleLogicException(HttpServletRequest request, LogicException exception) {
        String message = exception.getMessage();
        List<String> errors = new ArrayList<>();
        errors.add(message);
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.FAIL.code, message, data);
    }

    /**
     * 无数据异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(NoResultException.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> handleNoResultException(HttpServletRequest request, NoResultException exception) {
        String message = exception.getMessage();
        List<String> errors = new ArrayList<>();
        errors.add(message);
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.SUCCESS.code, message, data);
    }

    /**
     * 请求参数处理返回出现的错误提示
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseResult<Map<String, Object>> handleBindException(MethodArgumentNotValidException exception) {
        BindingResult bindingResult = exception.getBindingResult();
        List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
        List<String> errors = new ArrayList<>();
        for (FieldError fieldError : fieldErrorList) {
            errors.add(fieldError.getDefaultMessage());
        }
        Map<String, Object> data = new HashMap<>();
        data.put("errors", errors);
        return BaseResponse.makeRsp(ResponseCode.FAIL.code, "请求参数不正确", data);
    }

    /**
     * 请求参数处理返回出现的错误提示
     *
     * @param exception
     * @return
     */
//    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
//    public ResponseResult<Map<String, Object>> handleBindException(Exception exception) {
//        if (exception instanceof MethodArgumentNotValidException) {
//            BindingResult bindingResult = ((MethodArgumentNotValidException) exception).getBindingResult();
//            List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
//            List<String> errors = new ArrayList<>();
//            for (FieldError fieldError : fieldErrorList) {
//                errors.add(fieldError.getDefaultMessage());
//            }
//            Map<String, Object> data = new HashMap<>();
//            data.put("errors", errors);
//            return BaseResponse.makeRsp(ResponseCode.FAIL.code, "请求参数不正确", data);
//        }
//        return BaseResponse.makeRsp(ResponseCode.FAIL.code, "请求参数不正确", null);
//    }
}
